package me.hunche.app.service.impl;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import me.hunche.app.dao.SMSDao;
import me.hunche.app.domain.SMS;
import me.hunche.app.service.SMSService;
import me.hunche.app.sms.SMSHandler;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.emay.sdk.client.api.Client;
import cn.emay.sdk.client.api.MO;

//@Service
public class EmaySMSService implements SMSService,DisposableBean,InitializingBean{
	
	private static final Logger logger = Logger.getLogger(EmaySMSService.class);
	private static final String config = "/emay.properties";
	private Client client;
	@Autowired private SMSDao smsDao;
	
	private Integer queryInterval = 30; //n seconds
	private Integer timeout;
	private Map<String,SMSHandler> hds = new HashMap<String,SMSHandler>();
//	@Autowired private SMSHandler hd;
	
	private String signature = "【菲翔车队】";
	
	public void setSignature(String signature) {
		this.signature = signature;
	}

	private Properties p = new Properties();
	private Timer timer;
	
	@SuppressWarnings("deprecation")
	public void afterPropertiesSet() throws Exception {
		timer = new Timer();
		timer.schedule(new QueryMT(), queryInterval*1000, queryInterval*1000);
		
		loadProperties();
		try {
			client=new Client(p.getProperty("softwareSerialNo"),p.getProperty("key"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public class QueryMT extends TimerTask{
		public void run() {
			receiveMessage();
		}
	}

	public void destroy() throws Exception {
		timer.cancel();
		timer = null;
	}
	
	protected void loadProperties() {
		try {
			p.load(EmaySMSService.class.getResourceAsStream(config));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	

	public void sendMessage(List<String> recipients, String content) {
		String[] rs = new String[recipients.size()];
		sendMessage(recipients.toArray(rs),content);
	}

	public void sendMessage(String[] recipients, String content) {
		if (logger.isDebugEnabled()) {
			logger.debug("sendMessage recipients=" + Arrays.toString(recipients) + ",content=" + content + " - start");
		}
		int code = -1;
		
		try {
			code = client.sendSMS(recipients, content+signature,"",5);//带扩展码
		} catch (Exception e) {
			logger.error("sendMessage faild!msg->"+e.getMessage());
			e.printStackTrace();
		}
		
		if(code!=0){
			logger.error("sendMessage faild!code="+code);
		}
		if (logger.isInfoEnabled()) {
			logger.info("sendMessage recipients=" + Arrays.toString(recipients) + ",content=" + content + ",code=" +code+ " - end");
		}
	}
	
	public void sendMessage(String recipient,String content) {
		sendMessage(new String[]{recipient},content);
	}
	
	private DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

	
	public List<SMS> receiveMessage() {
		try {
			List<MO> list = client.getMO();
			
			if (list != null) {
				List<SMS> ms = new ArrayList();	
				
				for(MO mo : list) {
//				for(int i=list.size()-1;i>=0;i--){
//					MO mo = list.get(i);
					String mobile = mo.getMobileNumber();
					String content = mo.getSmsContent();
					Date stime = df.parse(mo.getSentTime());
					
					mo.getSentTime();
					ms.add(new SMS( mobile, content,SMS.TYPE_MO,stime));
					if (logger.isInfoEnabled()) {
	 					logger.info("Received message "+mobile +" "+content +" "+mo.getSentTime());
	 				}
					
					
					boolean handle = false;
	
					for(Entry<String, SMSHandler> item:hds.entrySet()){
	        			if(content!=null && content.toUpperCase().startsWith(item.getKey())){
	        				try {
	        					handle = item.getValue().execute(mobile, content);
	        					if(handle){
	            					break;
	            				}
							} catch (Exception e) {
								logger.error("SMShandle faild!msg->"+ e.getMessage());
								e.printStackTrace();
								continue;
							}
	        			}
	        		}
					if(!handle){
						logger.info("Received message "+mobile +" "+content +" "+mo.getSentTime() +" no handle");
					}
				}
				
				smsDao.saves(ms);
				
				if (logger.isInfoEnabled()) {
					logger.info("Received message "+list.size());
				}
				return ms;
			} else {
//				logger.debug("NO HAVE MO");
			}
		
		} catch (Exception e) {
			logger.info("receiveMessage faild!msg-> "+e.getMessage());
			e.printStackTrace();
		}
		
		return null;
	}


	public void registerHandler(SMSHandler handler) {
		logger.info("registerHandler "+handler.getPrefix().toUpperCase() +" "+handler.getClass().getName());
		hds.put(handler.getPrefix().toUpperCase(), handler);
	}

	public void sendScheduledMessage(final List<String> recipients, final String content,Date sendTime) {
		timer.schedule(new TimerTask() {
			public void run() {
				sendMessage(recipients, content);
			}
		}, sendTime);
	}

	public void sendScheduledMessage(final String recipient,final String content,
			Date sendTime) {
		timer.schedule(new TimerTask() {
			public void run() {
				sendMessage(recipient, content);
			}
		}, sendTime);
	}
}
